<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body></body>
</html>
<script>
  // 问题解答
  // new Promise实例，而且要 return
  // new Promise时要传入函数，函数有 resolve reject 两个参数
  // 成功时执行resolve()失败时执行reject()
  // then监听结果

  // 定义一个对象，包含伪私有成员 year_和公共成员 edition
  // 定义一个book对象
  // let book = {
  //     year_: 2017,
  //     edition: 1
  // };
  // // 使用Object.defineProperty方法定义year属性，并设置getter和setter方法
  // Object.defineProperty(book, "year", {
  //     get() {
  //         return this.year_;
  //     },
  //     set(newValue) {
  //         // 如果新值大于2017
  //         if (newValue > 2017) {
  //             // 将新值赋值给year_属性
  //             this.year_ = newValue;
  //             // 将新值减去2017赋值给edition属性
  //             this.edition += newValue - 2017;
  //         }
  //     }
  // });
  // // 设置book.year的值为2018
  // book.year = 2020;
  // // 打印book.edition的值
  // console.log(book.edition); // 2

  // window 的 onload 事件和 DOMContentLoaded 事件

  // 第一个是当页面所有的资源（图片、音频、视频等）全部加载完毕才会触发
  // 第二个是当 DOM 结构加载完毕就会触发
  // 简单来说，页面的 load 事件会在 DOMContentLoaded 被触发之后才触发。

  // 假设我们有一个时间戳
  // let timestamp = 1672531200;

  // // 将时间戳转换为Date对象
  // let date = new Date(timestamp * 1000); // 注意：JavaScript中的时间戳是以毫秒为单位的，所以需要乘以1000

  // // 将Date对象格式化为字符串
  // let formattedTime = date.toLocaleString(); // 使用本地时间格式

  // console.log("时间戳", timestamp, "对应的时间是:", formattedTime);

  // // 实现js中 把时间戳转换成标准的书剑日期

  // let timestamp =  1672531200;
  // let date = new Date(timestamp * 1000)

  // let year = date.getFullYear();
  // let month = date.getMonth() + 1;
  // let day = date.getDate();

  // let formattedTime = year + "年" + month + "月" + day + "日";

  // console.log("时间戳", timestamp, "对应的书剑日期是:", formattedTime);

  // 递归实现1-100的累加

  // function sum(n){
  //     if(n === 1){
  //         return 1;
  //     }else{
  //         return n+ sum(n-1)
  //     }
  // }
  //  console.log(sum(100));

  // 手动实现new操作符
  function myNew(constructor, ...args) {
    // 1. 创建一个空对象
    let obj = {};

    // 2. 将这个空对象的原型指向构造函数的原型
    obj.__proto__ = constructor.prototype;

    // 3. 将构造函数的 this 绑定到新对象上，并执行构造函数
    let result = constructor.apply(obj, args);

    // 4. 如果构造函数返回一个对象，则返回这个对象，否则返回新创建的对象
    return result instanceof Object ? result : obj;
  }

  // 使用自定义的 myNew 来创建 Person 对象
  let person2 = myNew(Person, "Bob", 40);
  person2.sayHello(); // Hello, my name is Bob and I am 40 years old.
//   -----------------------------
// 在这个实现中：

// 创建空对象：let obj = {};
// 设置原型链：obj.__proto__ = constructor.prototype;
// 绑定 this 并执行构造函数：let result = constructor.apply(obj, args);
// 返回对象：检查构造函数的返回值，如果显式返回了一个对象，则返回这个对象；否则返回新创建的对象。

// 回答面试问题
// 当面试官问你 new 操作符具体做了什么时，你可以按上述步骤逐条解释：

// 创建一个空对象。
// 将空对象的原型链指向构造函数的原型。
// 将构造函数的 this 绑定到这个新对象上，同时执行构造函数。
// 如果构造函数返回一个对象，则返回这个对象，否则返回新创建的对象。
// 通过这些步骤，面试官将了解到你对 new 操作符背后机制的深入理解。




// 原型（Prototype）
// 每个 JavaScript 对象（除了原始类型）都有一个内部链接到另一个对象的引用，这个引用就是原型。
// 原型对象可以包含属性和方法，这些属性和方法可以被所有通过原型继承该原型的对象共享。

// 原型链（Prototype Chain）
// 原型链是多个对象通过原型链接在一起形成的链条。当我们访问对象的属性或方法时，JavaScript 引擎会首先检查
// 对象本身是否具有该属性或方法。如果没有，它会顺着原型链向上查找，直到找到为止。如果最终没有找到该属性或方法，
// 则返回 undefined。
</script>
